package progetto;

import peersim.cdsim.CDProtocol;
import peersim.config.Configuration;
import peersim.core.CommonState;
import peersim.core.Node;

public class Infection implements CDProtocol {

	
	private static final String PAR_SUCC = "probab_succ"; 
	
	private static final double DEF_PAR_SUCC = 60;
	
	private static final String PAR_LV_PROT = "lv_prot";
	
	private static final String PAR_STATUS_PROT = "status_prot";
	
	
	private static double probSucc;
	
	private static int lvPid;
	
	private static int statusPid;
	
	public Infection(String prefix) {
		
		probSucc = Configuration.getDouble(prefix + "." + PAR_SUCC, DEF_PAR_SUCC);
		if(probSucc > 100 || probSucc < 0)
			probSucc = DEF_PAR_SUCC;
		lvPid = Configuration.getPid(prefix + "." + PAR_LV_PROT);
		statusPid = Configuration.getPid(prefix + "." + PAR_STATUS_PROT);
		
	}
	
	@Override
	public void nextCycle(Node node, int protocolID) {
		// TODO Auto-generated method stub
		int currentRun = CommonState.getIntTime();
		NodeStatus status = (NodeStatus)node.getProtocol(statusPid);
		
		if(status.isInfected() && (status.getRunInfec() != currentRun)) {

			LocalView lv = (LocalView)node.getProtocol(lvPid);
			for(int i=0 ; i<lv.degree(); i++) {
				
				Node neighbor = lv.getNeighbor(i);
				NodeStatus statusNeigh = ((NodeStatus)neighbor.getProtocol(statusPid));
				//if the node has not already been infected previously and it has the infected SO and it isn't immune
				if(!statusNeigh.isInfected() && statusNeigh.isInfectedSO() && !statusNeigh.isImmune()) {
					double value = CommonState.r.nextDouble();
					
					if(value < (probSucc/100)) {
						//infection 
						statusNeigh.setRunInfec(currentRun);
						statusNeigh.setInfected(true);
					} 
					
				} 

			}

		}
		
	}
	
	
	
	
	/**
	 * Clone.
	 */
	public Object clone()
	{
		Infection inf = null;
		try { 
			inf = (Infection)super.clone(); }
		catch( CloneNotSupportedException e ) {} // never happens
		return inf;
	}

}
